/********************************************************************************
 * @file    logic.c
 * @author  your name
 * @brief   IO逻辑管理
 *******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "lo_logic.h"
#include <string.h>
#include <stdlib.h>
#include "main.h"
#include "bsp.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define ITEM_IMPORT(type, vaild_state, GPIOx, GPIO_Pin, callback) \
    {                                                             \
        0, 0, 0, type, vaild_state, Lo_Logic_State_Off, {GPIOx, GPIO_Pin}, callback}

/* 宏定义初始时间，根据具体需求设置 */
#define INITIAL_DELAY_TIME 100     // 示例：1000个时间单位的延时
#define INITIAL_KEEP_TIME 2000     // 示例：500个时间单位的保持时间
#define INITIAL_INTERVAL_TIME 2000 // 示例：2000个时间单位的间隔时间

/* Private macro -------------------------------------------------------------*/

/* Private function prototypes ----------------------------------------------*/

/* Private functions --------------------------------------------------------*/

/*
    输出逻辑回调函数，通过在s_lo_logic表中的索引进行操作
*/
void Lo_Logic_Output_Callback(uint8_t index);

/*
    输入逻辑回调函数，通过在s_lo_logic表中的索引进行操作
*/
void Lo_Logic_Input_Callback(uint8_t index);

/* Private variables --------------------------------------------------------*/
Lo_Logic_t s_lo_logic[] = {
    // PE13 输出模式
    ITEM_IMPORT(Lo_Logic_Type_Output, GPIO_PIN_RESET, {GPIOE, GPIO_PIN_13}, Lo_Logic_Output_Callback),
    // PA8  输入模式
    ITEM_IMPORT(Lo_Logic_Type_Input, GPIO_PIN_RESET, {GPIOA, GPIO_PIN_8}, Lo_Logic_Input_Callback),
};

/* Public variables ---------------------------------------------------------*/
uint8_t test_index = 0;
/* Public functions ---------------------------------------------------------*/

/**
 * @brief 初始化逻辑
 *
 * @author XX
 * @date 2025-01-30
 * @copyright Copyright (c) 2025
 * @version
 *   V1.0  2025-01-30  XX    First release
 */
void Lo_Logic_Init(void)
{
    // 逻辑项0 输出项 初始化
    s_lo_logic[0].delay_time = INITIAL_DELAY_TIME;
    s_lo_logic[0].interval_time = INITIAL_INTERVAL_TIME;
    s_lo_logic[0].keep_time = INITIAL_KEEP_TIME;

    // 逻辑项1 输入项 初始化
    s_lo_logic[1].delay_time = 0;
    s_lo_logic[1].interval_time = 0;
    s_lo_logic[1].keep_time = 0;
}

/**
 * @brief 获取逻辑项数量
 *
 * @return uint8_t
 *
 * @author XX
 * @date 2025-01-30
 * @copyright Copyright (c) 2025
 * @version
 *   V1.0  2025-01-30  XX    First release
 */
uint8_t Lo_Logic_GetNum(void)
{
    return sizeof(s_lo_logic) / sizeof(Lo_Logic_t);
}

/**
 * @brief 输出逻辑回调函数，通过在s_lo_logic表中的索引来判断具体逻辑项
 *
 *
 * @author XX
 * @date 2025-01-31
 * @copyright Copyright (c) 2025
 * @version
 *   V1.0  2025-01-31  XX    First release
 */
void Lo_Logic_Output_Callback(uint8_t index)
{
    switch (index)
    {
    case 0:
        test_index = 1;
        break;

    default:
        // 意料之外的索引
        Bsp_SoftBreakPoint();
        break;
    }
}

/**
 * @brief 输入逻辑回调函数，通过在s_lo_logic表中的索引来判断具体逻辑项
 *
 * @param index
 *
 * @author XX
 * @date 2025-01-31
 * @copyright Copyright (c) 2025
 * @version
 *   V1.0  2025-01-31  XX    First release
 */
void Lo_Logic_Input_Callback(uint8_t index)
{
    switch (index)
    {
    case 0:
        test_index = 2;
        break;
    }
}

/**
 * @brief 逻辑管理 （需要放到1ms中断中）
 *
 * @author XX
 * @date 2025-01-30
 * @copyright Copyright (c) 2025
 * @version
 *   V1.0  2025-01-30  XX    First release
 */
void Lo_Logic_Manage(void)
{
    // 获取逻辑项数量
    uint8_t logic_item_num = Lo_Logic_GetNum();
    for (uint8_t i = 0; i < logic_item_num; i++)
    {
        Lo_Logic_t *item = Get_Lo_Logic_Item(i);
        if (item == NULL)
        {
            Bsp_SoftBreakPoint();
            continue;
        }

        switch (item->state)
        {
        case Lo_Logic_State_Off:
            if (g_Bsp_vars.is_debug)
            {
                item->delay_time = INITIAL_DELAY_TIME;
                item->state = Lo_Logic_State_Delay;
            }
            break;

        case Lo_Logic_State_Delay:
            if (item->delay_time > 0)
            {
                item->delay_time--;
            }
            if (item->delay_time == 0)
            {
                // 延时时间结束，需要触发操作
                if (item->type == Lo_Logic_Type_Output)
                {
                    HAL_GPIO_WritePin(item->mapping.output.GPIOx, item->mapping.output.GPIO_Pin, !item->vaild_state);
#ifdef USE_CALLBACK
                    item->callback(i);
#endif
                    item->keep_time = INITIAL_KEEP_TIME; // 设置保持时间
                }
                else if (item->type == Lo_Logic_Type_Input)
                {
#ifdef USE_CALLBACK
                    item->callback(i);
#endif
                }
                item->state = Lo_Logic_State_On;
            }
            break;

        case Lo_Logic_State_On:
            if (item->keep_time > 0)
            {
                item->keep_time--;
            }
            if (item->keep_time == 0)
            {
                if (item->type == Lo_Logic_Type_Output)
                {
                    HAL_GPIO_WritePin(item->mapping.output.GPIOx, item->mapping.output.GPIO_Pin, item->vaild_state);
                    item->interval_time = INITIAL_INTERVAL_TIME; // 设置间隔时间
                }
                else if (item->type == Lo_Logic_Type_Input)
                {
                }
                item->state = Lo_Logic_State_Interval;
            }
            break;

        case Lo_Logic_State_Interval:
            if (item->interval_time > 0)
            {
                item->interval_time--;
            }
            if (item->interval_time == 0)
            {
                item->state = Lo_Logic_State_Off;
            }
            break;

        default:
            // 处理未定义的状态
            Bsp_SoftBreakPoint();

            break;
        }
    }
}

/**
 * @brief 获取逻辑项
 *
 * @return Lo_Logic_t*
 *
 * @author XX
 * @date 2025-01-30
 * @copyright Copyright (c) 2025
 * @version
 *   V1.0  2025-01-30  XX    First release
 */
Lo_Logic_t *Get_Lo_Logic_Item(uint8_t index)
{
    return &s_lo_logic[index];
}
/************************ (C) COPYRIGHT Your Company *****END OF FILE****/
